package com.springboot.file.util.easyexcel.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.springboot.file.util.easyexcel.annotation.ExcelValidate;
import com.springboot.file.util.easyexcel.exception.ExcelValidationException;
import com.springboot.file.util.easyexcel.validator.ExcelValidator;
import com.springboot.file.util.easyexcel.EasyExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import com.springboot.file.util.easyexcel.exception.BatchProcessingException;
import com.springboot.file.util.easyexcel.exception.ExcelProcessingException;
import com.springboot.file.util.easyexcel.exception.ExcelImportException;
import lombok.Getter;
import lombok.Setter;

/**
 * 抽象监听器类 - 高性能多线程实现
 * @param <T> 实体类型
 */
@Slf4j
public abstract class AbstractBusinessListener<T> implements ReadListener<T> {
    /**
     * 默认批处理大小 - 可由子类自定义
     */
    protected int batchSize = 500;

    /**
     * 处理器核心数
     */
    private static final int CPU_CORES = Runtime.getRuntime().availableProcessors();

    /**
     * 最大并行批次数 - 避免创建过多线程 (留1个核心给系统使用)
     */
    private static final int MAX_PARALLEL_BATCHES = Math.max(2, CPU_CORES - 1);

    /**
     * 用于存储读取的数据
     */
    private final List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(batchSize);

    /**
     * 用于记录处理的总记录数
     */
    private final AtomicLong totalCount = new AtomicLong(0);

    /**
     * 成功处理的记录数
     */
    private final AtomicLong successCount = new AtomicLong(0);

    /**
     * 批次计数器
     */
    private final AtomicInteger batchCounter = new AtomicInteger(0);

    /**
     * 异步任务列表
     */
    private final List<Future<?>> taskFutures = new CopyOnWriteArrayList<>();

    /**
     * 错误记录
     */
    private final ConcurrentHashMap<Integer, String> errorRecords = new ConcurrentHashMap<>();

    /**
     * 开始时间
     */
    private long startTime;

    /**
     * 是否记录详细日志
     */
    protected boolean verboseLogging = false;

    /**
     * Sheet名称
     */
    private String sheetName;

    /**
     * Sheet序号
     */
    private int sheetNo;

    /**
     * 事务上下文，用于跨监听器事务管理
     */
    @Getter
    @Setter
    private EasyExcelUtil.TransactionContext transactionContext;
    
    /**
     * 是否为验证模式（仅验证数据，不保存）
     */
    @Getter
    @Setter
    private boolean validationMode = false;

    @Resource
    protected ThreadPoolTaskExecutor executor;

    @Override
    public void invoke(T data, AnalysisContext context) {
        // 检查是否是第一条数据，用于初始化处理
        if (startTime == 0) {
            // 记录开始时间和sheet信息
            startTime = System.currentTimeMillis();
            sheetName = context.readSheetHolder().getSheetName();
            sheetNo = context.readSheetHolder().getSheetNo();

            // 记录导入开始
            if (verboseLogging) {
                log.info("开始导入Sheet[{}:{}]", sheetNo, sheetName);
            }
        }

        // 记录总数
        totalCount.incrementAndGet();

        // 添加到缓存列表之前先进行字段校验
        try {
            validateData(data, context.readRowHolder().getRowIndex() + 1);
        } catch (ExcelValidationException e) {
            // 确保异常包含完整的Sheet信息
            if ("未知".equals(e.getSheetName()) || e.getSheetIndex() == -1) {
                // 使用当前sheet信息创建新的异常
                ExcelValidationException enhancedException = new ExcelValidationException(
                    e.getRowIndex(),
                    e.getErrorMessages(),
                    sheetName,
                    sheetNo
                );
                
                // 记录校验错误并抛出
                log.error("数据校验失败，Sheet[{}:{}] 第{}行：{}", 
                        sheetNo, sheetName, e.getRowIndex(), e.getErrorMessages());
                throw enhancedException;
            } else {
                // 记录校验错误并直接抛出，已经包含完整信息
                log.error("数据校验失败，Sheet[{}:{}] 第{}行：{}", 
                        e.getSheetIndex(), e.getSheetName(), e.getRowIndex(), e.getErrorMessages());
                throw e;
            }
        }

        // 添加到缓存列表
        cachedDataList.add(data);

        // 达到批处理大小时，提交批量处理
        if (cachedDataList.size() >= batchSize) {
            processBatch(context);
        }
    }

    /**
     * 处理一批数据
     */
    private void processBatch(AnalysisContext context) {
        // 控制并发批次数量，避免系统资源耗尽
        if (taskFutures.size() >= MAX_PARALLEL_BATCHES) {
            waitForSomeBatchesToComplete();
        }

        // 准备批处理数据
        int batchNum = batchCounter.incrementAndGet();
        final List<T> dataToProcess = prepareDataForProcessing();
        final int rowOffset = context.readRowHolder().getRowIndex() - dataToProcess.size() + 1;
        
        // 如果在事务模式下且已有失败，或者是验证模式，则跳过处理
        if (shouldSkipProcessing(batchNum)) {
            return;
        }

        // 根据事务模式选择处理方式
        if (transactionContext != null) {
            processInTransactionMode(dataToProcess, batchNum, rowOffset);
        } else {
            processAsynchronously(dataToProcess, batchNum, rowOffset);
        }
    }
    
    /**
     * 准备批处理数据
     */
    private List<T> prepareDataForProcessing() {
        // 创建新列表，避免并发修改
        final List<T> dataToProcess = new ArrayList<>(cachedDataList);
        
        if (verboseLogging) {
            log.info("Sheet[{}:{}] 提交第{}批数据处理，大小: {}", 
                    sheetNo, sheetName, batchCounter.get(), dataToProcess.size());
        }
        
        // 清空缓存列表
        cachedDataList.clear();
        return dataToProcess;
    }
    
    /**
     * 判断是否应该跳过处理
     */
    private boolean shouldSkipProcessing(int batchNum) {
        // 如果在事务模式下且已有失败，跳过后续处理
        if (isTransactionFailed()) {
            if (verboseLogging) {
                log.warn("Sheet[{}:{}] 检测到事务已失败，跳过批处理", sheetNo, sheetName);
            }
            return true;
        }
        
        // 如果是验证模式，跳过保存操作，仅进行数据验证
        if (validationMode) {
            if (verboseLogging) {
                log.debug("Sheet[{}:{}] 处于验证模式，批次{}跳过保存操作", sheetNo, sheetName, batchNum);
            }
            return true;
        }
        
        return false;
    }
    
    /**
     * 在事务模式下处理数据
     */
    private void processInTransactionMode(List<T> dataToProcess, int batchNum, int rowOffset) {
        try {
            // 再次检查事务状态（可能在准备过程中状态已变化）
            if (isTransactionFailed()) {
                if (verboseLogging) {
                    log.warn("Sheet[{}:{}] 批次{}检测到事务已失败，跳过处理", sheetNo, sheetName, batchNum);
                }
                return;
            }
            
            // 同步处理数据
            int processed = saveData(dataToProcess);
            // 累加成功处理的记录数
            successCount.addAndGet(processed);

            if (verboseLogging) {
                log.info("Sheet[{}:{}] 第{}批完成，处理记录数: {}/{}",
                        sheetNo, sheetName, batchNum, processed, dataToProcess.size());
            }
        } catch (Exception e) {
            handleBatchProcessingError(e, dataToProcess, batchNum, rowOffset);
        }
    }
    
    /**
     * 异步处理数据（非事务模式）
     */
    private void processAsynchronously(List<T> dataToProcess, int batchNum, int rowOffset) {
        Future<?> future = executor.submit(() -> {
            try {
                // 处理数据
                int processed = saveData(dataToProcess);
                // 累加成功处理的记录数
                successCount.addAndGet(processed);

                if (verboseLogging) {
                    log.info("Sheet[{}:{}] 第{}批完成，处理记录数: {}/{}",
                            sheetNo, sheetName, batchNum, processed, dataToProcess.size());
                }
            } catch (Exception e) {
                // 记录批处理异常
                log.error("Sheet[{}:{}] 第{}批处理异常: {}", sheetNo, sheetName, batchNum, e.getMessage(), e);

                // 记录详细错误信息 - 批量错误时记录大致行号
                recordBatchErrors(dataToProcess, batchNum, rowOffset, e.getMessage());
            }
        });

        taskFutures.add(future);
    }
    
    /**
     * 处理批处理错误
     */
    private void handleBatchProcessingError(Exception e, List<T> dataToProcess, int batchNum, int rowOffset) {
        // 记录批处理异常
        log.error("Sheet[{}:{}] 第{}批处理异常: {}", sheetNo, sheetName, batchNum, e.getMessage(), e);

        // 记录详细错误信息
        recordBatchErrors(dataToProcess, batchNum, rowOffset, e.getMessage());
        
        // 标记事务失败
        String errorMsg = String.format("Sheet[%d:%s] 批次%d处理失败: %s", 
                                      sheetNo, sheetName, batchNum, e.getMessage());
        markTransactionAsFailed(errorMsg);
        
        // 抛出专用异常确保事务回滚
        throw new BatchProcessingException(
            e.getMessage(), e, batchNum, sheetName, sheetNo, rowOffset
        );
    }
    
    /**
     * 记录批处理错误
     */
    private void recordBatchErrors(List<T> dataToProcess, int batchNum, int rowOffset, String errorMessage) {
        for (int i = 0; i < dataToProcess.size(); i++) {
            int rowNum = rowOffset + i;
            errorRecords.put(rowNum, String.format("批处理异常(批次%d): %s", batchNum, errorMessage));
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理剩余数据
        if (!cachedDataList.isEmpty()) {
            processBatch(context);
        }

        // 等待所有异步任务完成
        waitForAllTasksComplete();

        // 计算性能指标并记录
        long duration = System.currentTimeMillis() - startTime;
        long totalRecords = totalCount.get();
        long successRecords = successCount.get();
        int errorCount = errorRecords.size();
        double recordsPerSecond = totalRecords * 1000.0 / Math.max(1, duration);

        // 检查是否存在错误
        if (errorCount > 0) {
            String errorMsg = String.format("Sheet[%d:%s] 导入出现 %d 个错误", sheetNo, sheetName, errorCount);
            log.error(errorMsg);
            
            if (transactionContext != null) {
                markTransactionAsFailed(errorMsg);
                
                // 在事务模式下，根据当前阶段决定是否抛出异常
                if (validationMode) {
                    // 在验证模式下，记录错误但不抛出异常，让验证继续进行
                    log.warn("验证模式：{}", errorMsg);
                } else {
                    // 在保存模式下，抛出专用异常以触发回滚
                    throw new ExcelImportException(errorMsg, sheetName, sheetNo, errorCount);
                }
            }
        }

        if (validationMode) {
            log.info("Sheet[{}:{}] 验证完成 - 总记录: {}, 错误: {}, 耗时: {}ms", 
                   sheetNo, sheetName, totalRecords, errorCount, duration);
        } else {
            log.info("Sheet[{}:{}] 导入完成 - 总记录: {}, 成功: {}, 错误: {}, 耗时: {}ms, 速度: {}/s",
                   sheetNo, sheetName, totalRecords, successRecords, errorCount,
                   duration, String.format("%.1f", recordsPerSecond));
        }

        // 执行子类的后处理逻辑
        if (!validationMode) {
            afterImportComplete(totalRecords, successRecords, errorRecords, context);
        }
    }

    /**
     * 等待所有异步任务完成
     */
    private void waitForAllTasksComplete() {
        try {
            long startWaitTime = System.currentTimeMillis();
            long maxWaitTimeMillis = TimeUnit.MINUTES.toMillis(10); // 最多等待10分钟

            while (!Thread.currentThread().isInterrupted()) {
                // 移除已完成的任务，并检查是否全部完成
                boolean allDone = removeCompletedTasksAndCheckIfAllDone();

                // 如果全部完成，记录日志并返回
                if (allDone) {
                    log.info("所有批次处理完成");
                    return;
                }

                // 检查是否超时
                if (isWaitTimedOut(startWaitTime, maxWaitTimeMillis)) {
                    break;
                }

                // 日志记录和短暂休眠
                logRemainingTasksIfVerbose();
                TimeUnit.MILLISECONDS.sleep(500);// 减少检查频率
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("等待批次处理完成被中断", e);
        }
    }

    /**
     * 移除已完成的任务，并检查是否全部完成
     * @return 如果所有任务完成返回true，否则返回false
     */
    private boolean removeCompletedTasksAndCheckIfAllDone() {
        List<Future<?>> completedTasks = new ArrayList<>();

        // 收集已完成的任务
        for (Future<?> future : taskFutures) {
            if (future.isDone()) {
                completedTasks.add(future);
            }
        }

        // 从列表中移除已完成的任务
        taskFutures.removeAll(completedTasks);

        // 如果没有剩余任务，则全部完成
        return taskFutures.isEmpty();
    }

    /**
     * 检查等待是否已超时
     * @param startWaitTime 开始等待的时间戳
     * @param maxWaitTimeMillis 最大等待时间（毫秒）
     * @return 如果已超时返回true，否则返回false
     */
    private boolean isWaitTimedOut(long startWaitTime, long maxWaitTimeMillis) {
        if (System.currentTimeMillis() - startWaitTime > maxWaitTimeMillis) {
            log.warn("等待批次处理超时，仍有{}个批次未完成", taskFutures.size());
            return true;
        }
        return false;
    }

    /**
     * 如果启用了详细日志，记录剩余任务数
     */
    private void logRemainingTasksIfVerbose() {
        if (verboseLogging && !taskFutures.isEmpty()) {
            log.debug("还剩{}个批次正在处理中...", taskFutures.size());
        }
    }

    /**
     * 异常处理
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        int rowIndex = context.readRowHolder().getRowIndex() + 1;
        
        if (exception instanceof ExcelDataConvertException exceldataconvertexception) {
            handleDataConvertException(exceldataconvertexception, rowIndex);
        } else if (exception instanceof ExcelValidationException excelvalidationexception) {
            handleValidationException(excelvalidationexception);
        } else {
            handleGenericException(exception, rowIndex);
        }
    }
    
    /**
     * 处理数据转换异常
     */
    private void handleDataConvertException(ExcelDataConvertException convertException, int rowIndex) {
        int columnIndex = convertException.getColumnIndex() + 1;
        String cellData = String.valueOf(convertException.getCellData());
        
        String errorMsg = String.format("第%d行，第%d列数据[%s]格式错误", 
                                     rowIndex, columnIndex, cellData);
        log.error(errorMsg, convertException);
        
        // 记录错误
        errorRecords.put(rowIndex, errorMsg);
        
        // 标记事务为失败状态
        markTransactionAsFailed(errorMsg);
        
        // 处理异常传播
        processExceptionPropagation(
            new ExcelProcessingException(
                errorMsg, convertException, rowIndex, columnIndex, sheetName, sheetNo
            )
        );
    }
    
    /**
     * 处理数据校验异常
     */
    private void handleValidationException(ExcelValidationException validationException) {
        // 确保异常包含完整的Sheet信息
        validationException = ensureCompleteSheetInfo(validationException);
        
        // 构造包含完整信息的错误消息
        String errorMsg = String.format("Sheet[%d:%s] 第%d行数据校验失败：%s", 
                                     validationException.getSheetIndex(),
                                     validationException.getSheetName(),
                                     validationException.getRowIndex(), 
                                     String.join(", ", validationException.getErrorMessages()));
        log.error(errorMsg);
        
        // 记录错误
        errorRecords.put(validationException.getRowIndex(), errorMsg);
        
        // 标记事务为失败状态
        markTransactionAsFailed(errorMsg);
        
        // 处理异常传播 - 直接传播原始的校验异常
        processExceptionPropagation(validationException);
    }
    
    /**
     * 确保校验异常包含完整的Sheet信息
     */
    private ExcelValidationException ensureCompleteSheetInfo(ExcelValidationException validationException) {
        // 如果没有Sheet信息，创建一个新的异常，包含当前Sheet的信息
        if ("未知".equals(validationException.getSheetName()) || validationException.getSheetIndex() == -1) {
            return new ExcelValidationException(
                validationException.getRowIndex(),
                validationException.getErrorMessages(),
                sheetName,
                sheetNo
            );
        }
        return validationException;
    }
    
    /**
     * 处理通用异常
     */
    private void handleGenericException(Exception exception, int rowIndex) {
        String errorMsg = String.format("第%d行数据处理异常：%s", rowIndex, exception.getMessage());
        log.error(errorMsg, exception);
        
        // 记录错误
        errorRecords.put(rowIndex, errorMsg);
        
        // 标记事务为失败状态
        markTransactionAsFailed(errorMsg);
        
        // 处理异常传播
        processExceptionPropagation(
            new ExcelProcessingException(
                errorMsg, exception, rowIndex, -1, sheetName, sheetNo
            )
        );
    }
    
    /**
     * 处理异常传播
     */
    private void processExceptionPropagation(Exception exceptionToThrow) {
        // 在验证模式下，异常不会中断其他sheet的验证过程，但会被记录在事务上下文中
        // 在保存模式下，抛出异常确保异常传播并触发回滚
        if (transactionContext == null || !validationMode) {
            throw exceptionToThrow instanceof RuntimeException ? 
                  (RuntimeException) exceptionToThrow :
                  new RuntimeException(exceptionToThrow.getMessage(), exceptionToThrow);
        }
        // 即使在验证模式下，也需要确保将ExcelValidationException记录到事务上下文中
        // 这样这些异常也能被捕获并返回给前端
        if (exceptionToThrow instanceof ExcelValidationException) {
            ExcelValidationException validationException = (ExcelValidationException) exceptionToThrow;
            if (transactionContext != null) {
                transactionContext.setFailed(true);
                transactionContext.setErrorMessage(validationException.getMessage());
                // 即使在验证模式下也需要抛出，确保错误被传播
                throw validationException;
            }
        }
    }

    /**
     * 抽象方法，由子类实现具体的保存逻辑
     * @param dataList 数据列表
     * @return 成功处理的记录数
     */
    protected abstract int saveData(List<T> dataList);

    /**
     * 导入完成后的处理，子类可以覆盖此方法提供额外的逻辑
     * @param total 总记录数
     * @param success 成功处理数
     * @param errors 错误记录
     * @param context 分析上下文
     */
    protected void afterImportComplete(long total, long success, ConcurrentHashMap<Integer, String> errors, AnalysisContext context) {
        // 默认实现为空，子类可以根据需要覆盖此方法
    }

    /**
     * 处理表头信息，由子类根据需要重写此方法
     * 此方法不会自动被调用，需要在invoke方法中手动调用
     *
     * @param headMap 表头映射
     * @param context 解析上下文
     */
    protected void processHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 默认实现为空，子类可以根据需要重写此方法处理表头信息
    }

    /**
     * 校验数据
     * 
     * @param data 单条数据
     * @param rowIndex 行号（从1开始）
     * @throws ExcelValidationException 如果校验失败则抛出异常
     */
    protected void validateData(T data, int rowIndex) {
        if (data == null) {
            return;
        }
        
        // 记录校验开始，方便调试
        if (verboseLogging) {
            log.debug("开始校验Sheet[{}:{}]第{}行数据", sheetNo, sheetName, rowIndex);
        }
        
        // 获取所有字段，包括父类字段
        Class<?> clazz = data.getClass();
        Field[] fields = clazz.getDeclaredFields();
        
        // 获取使用ExcelValidate注解的字段
        List<Field> validateFields = Arrays.stream(fields)
                .filter(field -> field.isAnnotationPresent(ExcelValidate.class))
                .toList();
        
        // 如果没有需要校验的字段，直接返回
        if (CollUtil.isEmpty(validateFields)) {
            return;
        }
        
        // 收集错误信息
        List<String> errorMessages = new ArrayList<>();
        
        // 处理ExcelValidate注解的字段
        for (Field field : validateFields) {
            try {
                // 获取属性名称
                String propertyName = field.getName();
                
                // 使用Getter方法来获取字段值
                Method getterMethod = findGetterMethod(clazz, propertyName, errorMessages);
                if (getterMethod == null) {
                    continue; // 没有找到getter方法，跳过此字段
                }
                
                // 调用getter方法获取值
                Object value = getterMethod.invoke(data);
                
                // 获取注解
                ExcelValidate annotation = field.getAnnotation(ExcelValidate.class);
                String fieldName = ObjectUtil.isNotEmpty(annotation.fieldName()) ? 
                        annotation.fieldName() : propertyName;
                
                // 执行校验
                validateField(value, annotation, fieldName, errorMessages);
                
            } catch (InvocationTargetException e) {
                log.error("调用getter方法异常: {}", e.getCause().getMessage(), e);
                errorMessages.add("字段[" + field.getName() + "]调用getter方法异常: " + e.getCause().getMessage());
            } catch (Exception e) {
                log.error("字段校验异常: {}", e.getMessage(), e);
                errorMessages.add("字段[" + field.getName() + "]校验时发生异常: " + e.getMessage());
            }
        }
        
        // 如果有错误，则抛出异常
        if (!errorMessages.isEmpty()) {
            log.error("Sheet[{}:{}] 第{}行数据校验失败：{}", sheetNo, sheetName, rowIndex, String.join(", ", errorMessages));
            throw new ExcelValidationException(rowIndex, errorMessages, sheetName, sheetNo);
        }
    }
    
    /**
     * 查找属性的getter方法
     * 
     * @param clazz 类
     * @param propertyName 属性名
     * @param errorMessages 错误信息收集列表
     * @return getter方法，如果未找到则返回null
     */
    private Method findGetterMethod(Class<?> clazz, String propertyName, List<String> errorMessages) {
        // 尝试使用标准getter命名规则查找方法
        String getterMethodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        try {
            return clazz.getMethod(getterMethodName);
        } catch (NoSuchMethodException e) {
            // 对于boolean类型可能使用is前缀
            getterMethodName = "is" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
            try {
                return clazz.getMethod(getterMethodName);
            } catch (NoSuchMethodException ex) {
                // 如果没有getter方法，记录错误并继续
                log.error("无法找到{}的getter方法", propertyName);
                errorMessages.add("字段[" + propertyName + "]缺少getter方法");
                return null;
            }
        }
    }
    
    /**
     * 校验单个字段
     * 
     * @param value 字段值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     */
    private void validateField(Object value, ExcelValidate annotation,
                              String fieldName, List<String> errorMessages) throws Exception {
        // 1. 非空校验
        if (!validateRequired(value, annotation, fieldName, errorMessages)) {
            return; // 如果字段为空且是必填，则不进行后续校验
        }
        
        // 如果值为空且不是必填字段，跳过后续校验
        if (ObjectUtil.isEmpty(value)) {
            return;
        }
        
        // 2. 字符串校验（长度、正则表达式）
        if (value instanceof String string) {
            validateString(string, annotation, fieldName, errorMessages);
        }
        
        // 3. 数值范围校验
        if (value instanceof Number number) {
            validateNumber(number, annotation, fieldName, errorMessages);
        }
        
        // 4. 自定义校验器
        validateWithCustomValidator(value, annotation, fieldName, errorMessages);
    }
    
    /**
     * 非空校验
     * 
     * @param value 字段值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     * @return 如果校验通过或者不是必填字段返回true，否则返回false
     */
    private boolean validateRequired(Object value, ExcelValidate annotation,
                                  String fieldName, List<String> errorMessages) {
        if (annotation.required() && ObjectUtil.isEmpty(value)) {
            String message = getValidationMessage(fieldName, annotation.requiredMessage());
            errorMessages.add(message);
            return false;
        }
        return true;
    }
    
    /**
     * 字符串校验
     * 
     * @param value 字符串值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     */
    private void validateString(String value, ExcelValidate annotation, 
                               String fieldName, List<String> errorMessages) {
        // 字符串长度校验
        validateStringLength(value, annotation, fieldName, errorMessages);
        
        // 正则表达式校验
        validateRegex(value, annotation, fieldName, errorMessages);
    }
    
    /**
     * 字符串长度校验
     * 
     * @param value 字符串值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     */
    private void validateStringLength(String value, ExcelValidate annotation,
                                     String fieldName, List<String> errorMessages) {
        if (annotation.minLength() > -1 && value.length() < annotation.minLength()) {
            String message = String.format("%s长度不能小于%d个字符", fieldName, annotation.minLength());
            errorMessages.add(message);
        }
        
        if (annotation.maxLength() > -1 && value.length() > annotation.maxLength()) {
            String message = String.format("%s长度不能大于%d个字符", fieldName, annotation.maxLength());
            errorMessages.add(message);
        }
    }
    
    /**
     * 正则表达式校验
     * 
     * @param value 字符串值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     */
    private void validateRegex(String value, ExcelValidate annotation,
                              String fieldName, List<String> errorMessages) {
        if (!ObjectUtil.isEmpty(annotation.regex()) && !value.matches(annotation.regex())) {
            String message = String.format("%s格式不正确", fieldName);
            if (!ObjectUtil.isEmpty(annotation.message())) {
                message = annotation.message();
            }
            errorMessages.add(message);
        }
    }
    
    /**
     * 数值校验
     * 
     * @param value 数值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     */
    private void validateNumber(Number value, ExcelValidate annotation,
                               String fieldName, List<String> errorMessages) {
        double numValue = value.doubleValue();
        
        if (annotation.min() > Double.MIN_VALUE && numValue < annotation.min()) {
            String message = String.format("%s不能小于%s", fieldName, annotation.min());
            errorMessages.add(message);
        }
        
        if (annotation.max() < Double.MAX_VALUE && numValue > annotation.max()) {
            String message = String.format("%s不能大于%s", fieldName, annotation.max());
            errorMessages.add(message);
        }
    }
    
    /**
     * 使用自定义校验器进行校验
     * 
     * @param value 字段值
     * @param annotation 校验注解
     * @param fieldName 字段名称
     * @param errorMessages 错误信息收集列表
     * @throws Exception 校验器实例化异常
     */
    private void validateWithCustomValidator(Object value, ExcelValidate annotation,
                                           String fieldName, List<String> errorMessages) throws Exception {
        if (annotation.validator() == void.class) {
            return;
        }
        
        try {
            Class<?> validatorClass = annotation.validator();
            if (ExcelValidator.class.isAssignableFrom(validatorClass)) {
                // 实例化校验器
                ExcelValidator validator = (ExcelValidator) validatorClass.getDeclaredConstructor().newInstance();
                
                // 执行校验
                String validationError = validator.validate(value, fieldName);
                if (!ObjectUtil.isEmpty(validationError)) {
                    errorMessages.add(validationError);
                }
            }
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            log.error("实例化自定义校验器失败: {}", e.getMessage(), e);
            throw new IllegalArgumentException("自定义校验器实例化失败", e);
        }
    }
    
    /**
     * 获取校验消息
     * 
     * @param fieldName 字段名称
     * @param defaultMessage 默认消息
     * @return 格式化后的消息
     */
    private String getValidationMessage(String fieldName, String defaultMessage) {
        return String.format("%s%s", fieldName, defaultMessage);
    }

    /**
     * 获取Sheet名称
     */
    protected String getSheetName() {
        return this.sheetName;
    }

    /**
     * 获取Sheet编号
     */
    protected int getSheetNo() {
        return this.sheetNo;
    }

    /**
     * 检查事务上下文是否已标记为失败
     */
    protected boolean isTransactionFailed() {
        return transactionContext != null && transactionContext.isFailed();
    }

    /**
     * 标记事务上下文为失败状态
     */
    protected void markTransactionAsFailed(String errorMessage) {
        if (transactionContext != null) {
            log.warn("Sheet[{}:{}] 标记事务为失败状态: {}", sheetNo, sheetName, errorMessage);
            transactionContext.setFailed(true);
            transactionContext.setErrorMessage(errorMessage);
        }
    }

    /**
     * 等待部分批次完成，控制并发度
     */
    private void waitForSomeBatchesToComplete() {
        int targetCompletedCount = taskFutures.size() / 2; // 等待一半的任务完成
        int completedCount = 0;

        // 检查已完成的任务
        List<Future<?>> completedTasks = new ArrayList<>();
        for (Future<?> future : taskFutures) {
            if (future.isDone()) {
                completedTasks.add(future);
                completedCount++;
                if (completedCount >= targetCompletedCount) {
                    break;
                }
            }
        }

        // 从任务列表中移除已完成的任务
        taskFutures.removeAll(completedTasks);

        // 如果没有足够的已完成任务，等待一些任务完成
        if (completedCount < targetCompletedCount && !taskFutures.isEmpty()) {
            try {
                if (verboseLogging) {
                    log.debug("等待部分批次完成以控制并发度...");
                }
                Thread.sleep(100); // 短暂等待，避免忙等
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}